package com.sn.net;

import com.sn.bean.Address;
import com.sn.constant.Common;

import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description:
 * @Author: songbiao
 */
public class Server {


    private DatagramSocket socket;
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    //所有客户端信息
    public static ArrayList<Address> clients = new ArrayList();

    public final static Object LOCK = new Object();

    /**
     * 初始化
     * @param port
     */
    public Server(int port){
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void sendData(ArrayList<Address> clients, byte[] data){
        clients.forEach(address -> {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        int totalData = 0;
                        synchronized (LOCK) {
                            DatagramPacket packet = null;
                            int offset = 0;
                            int length = Common.TRANSFER_DATA;//每次发送60kb
                            int surplus = 0;//剩余字节
                            if (data.length<length) {
                                length = data.length;
                            }
                            while (true) {
                                packet = new DatagramPacket(data, offset, length,
                                        InetAddress.getByName(address.getHost()), address.getPort());
                                socket.send(packet);
                                totalData += length;
                                if (length!=Common.TRANSFER_DATA){
                                    //发送结束标志
                                    byte[] end = "end".getBytes();
                                    packet = new DatagramPacket(end,end.length,
                                            InetAddress.getByName(address.getHost()), address.getPort());
                                    socket.send(packet);
                                    break;//完成一次发送
                                }
                                offset += length;
                                if ((surplus = data.length - offset)<length) {
                                    length = surplus;//避免偏移超出数组长度
                                }
                            }
                        }
                        System.out.println("服务端--->客户端:"+address+"   数据大小:"+data.length+"byte  实际发送了:"+totalData+"byte");
                    } catch (UnknownHostException e) {
                        System.err.println("客户端地址解析失败..");
                        e.printStackTrace();
                    }catch (IOException e) {
                        System.err.println("服务端发送失败...");
                        e.printStackTrace();
                    }
                }
            });
        });
    }


    /**
     * 监听客户端连接
     */
    public void accept(){
        while (true) {
            System.out.println("服务端等待连接....");
            try {
                // 创建数据报，用于接收客户端发送的数据
                byte[] data = new byte[255];// 创建字节数组，指定接收的数据包的大小
                DatagramPacket packet = new DatagramPacket(data, data.length);
                socket.receive(packet);
                // 读取数据
                String clientIP = new String(data, 0, packet.getLength());
                String[] addressArray = clientIP.split(":");
                clients.add(new Address(addressArray[0]
                        ,Integer.valueOf(addressArray[1])));
                System.out.println("客户端已连接:" + clientIP);
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                System.err.println("接收客户端消息失败..");
            }
        }
    }

}
